#include "type.h"
#include "const.h"
#include "protectmode.h"
#include "prototype.h"
#include "keyboard.h"
#include "tty.h"
#include "global.h"


extern TTY tty[NR_TTY];
extern int8 currentTTY;
extern boolean print_story_flag;
extern boolean thread_test_flag;

int user_input_buff_max_size=512;
int8 user_input_buff[512];
int8 user_input_buff_index=0;
int8* user="root";
int8* password="rootroot";
boolean login=FALSE;
int8* OS_VERSION="0.0.1";
int8* OS_NAME="OS alpha";
PUBLIC boolean str_start_with(int8*,int8*);
PUBLIC int str_len(int8*);
PUBLIC boolean str_equal(int8* ,int8* );
PUBLIC void print(int8*);
PUBLIC void println(int8*);
PUBLIC void newline();





//简易的TTY
PUBLIC void initTTY()
{
		int i;
		/*		currentTTY = 0;
				for(i = 0;i < NR_TTY;i++)
				{
				tty[i].read.count = 0;
				tty[i].write.count = 0;
				tty[i].cooked.count = 0;
				tty[i].echo = TRUE;

				tty[i].read.head = tty[i].read.tail = tty[i].read.buf;
				tty[i].write.head = tty[i].write.tail = tty[i].write.buf;
				tty[i].cooked.head = tty[i].cooked.tail = tty[i].cooked.buf;

				memset(tty[i].read,0,TTY_BUF_SIZE);
				memset(tty[i].write,0,TTY_BUF_SIZE);
				memset(tty[i].cooked,0,TTY_BUF_SIZE);

				}
		 */		
		for(i=0;i<user_input_buff_max_size;i++){
				user_input_buff[i]=0;
		}
		user_input_buff_index=0;
}

PUBLIC boolean str_start_with(int8* tar,int8* src){
		int i=0;
		if(str_len(src)<str_len(tar)){
				return FALSE;
		}else{
				while(i<str_len(tar)-1 && i<str_len(src)-1){
						if(tar[i]!=src[i]){
								return FALSE;
						}
						i++;
				}
				if(src[i]==0 || src[i]==' '){
						return TRUE;
				}else{
						return FALSE;
				}
		}
}

PUBLIC int str_len(int8* str){
		int i=0;
		while(str[i]!=0){
				i++;
		}
		return ++i;
}

PUBLIC boolean str_equal(int8* tar,int8* src){
		int8 i=0;
		if(str_len(tar)!=str_len(src)){
				return FALSE;
		}
		while(i<str_len(tar) && i<str_len(src)){
				if(tar[i]!=src[i]){
						return FALSE;
				}
				i++;
		}
		return TRUE;
}

PUBLIC void newline(){
		print("\n");
}

PUBLIC void println(int8* str){
		print(str);
		newline();
}

PUBLIC void print(int8* str){
		disp_str(str);
}

PUBLIC void unknown_cmd(int8* str){
		//int color=0x4;
		//disp_color_str(str, color);
		//disp_color_str(": command not found", color);
		//newline();
		print(str);
		println(": command not found");
}

PUBLIC void echo(int8* str){
		println(str);
}

PUBLIC int you (int8 n)
{
		int p;
		if (n=='*'||n=='/') p=4;
		if (n=='+'||n=='-') p=3;
		if (n=='(') p=2;
		if (n==')') p=1;
		if (n=='\n') p=0;
		return p;
}

PUBLIC void calculate(int8* str){

		int c[1];
		
		int shu1;
		
		int shu2;
		
		int shu3;
		
		int b;

		int sum;
		
		char s[10],a,fuhao;
		int top1=0,top2=0,flag=0,flag2=0;
		int index;
		int8 out[2];
		out[1]=0;
		str="9+1";
		index=0;
		println("1");
		b=10;
		sum =0;
		println("2");
		//println(str);
		s[0]='\n';
		//printf("请输入一个表达式（以等号结束）\n");
		disp_int(index);newline();
		a=str[index++];
		disp_int(index);newline();
		while (a!='\0')
		{ 
		println("3");
				if ((a>='0'&&a<='9')||a=='.') 
				{
						flag2=1;
						if (a=='.') flag=1;     
						else {   
								if (flag==0)   
								{
										sum=sum*10+a-48;
								} else if (flag==1)
								{
										sum=sum+(a-48)/b;
										b=b*10;
								}
						}
						println("inner if");
				}else{ 
						if(flag2) 
						{
								top1++;
								c[top1]=sum; 
								b=10;
								flag=0;
								sum=0;
								flag2=0;
						}
						println("4");
						switch (a)
						{ 
								case '(':top2=top2+1; s[top2]=a;break;
								case ')': while(s[top2]!='(')
										  { 
												  shu1=c[top1];top1--;
												  shu2=c[top1];top1--;
												  fuhao=s[top2];top2--; 
												  switch(fuhao)
												  { 
														  case'+':shu3=shu2+shu1;break;
														  case'-':shu3=shu2-shu1;break;
														  case'*':shu3=shu2*shu1;break;
														  case'/':shu3=shu2/shu1;
												  }
												  top1++;
												  c[top1]=shu3;
										  }
										  top2=top2-1;
										  break;
								case'-':;
								case'*':;
								case'/':;
								case'+':
										while ( you(a)<=you(s[top2]))
										{
												shu1=c[top1];top1--;
												shu2=c[top1];top1--;
												fuhao=s[top2];top2--; 
												switch(fuhao)
												{ 
														case'+':shu3=shu2+shu1;break;
														case'-':shu3=shu2-shu1;break;
														case'*':shu3=shu2*shu1;break;
														case'/':shu3=shu2/shu1;
												}
												top1++;
												c[top1]=shu3;
										}         
										top2++;s[top2]=a; 
										break;
							default:out[0]=a;
							print("Error operation:");
							println(out);
									break;

						}
				}
				println("5");
				a=str[index++];
				out[0]=a;
				print("Processing:");
				println(out);
		}
		while(top2>0)
		{shu1=c[top1];top1--;shu2=c[top1];top1--;fuhao=s[top2];top2--; 
				switch(fuhao)
				{
						case'+':shu3=shu2+shu1;break;
						case'-':shu3=shu2-shu1;break;
						case'*':shu3=shu2*shu1;break;
						case'/':shu3=shu2/shu1;
				}
				println("6");
				top1++;c[top1]=shu3;
		}         
		//disp_int((int)c[top1]); 
		//println("ok!");
}



PUBLIC void superman(){
		println("               .=.,"); 
		println("              ;c =\\"); 
		println("            __|  _/"); 
		println("          .'-'-._/-'-._"); 
		println("         /..   ____    \\"); 
		println("        /' _  [<_->] )  \\"); 
		println("       (  / \\--\\_>/-/'._ )"); 
		println("        \\-;_/\\__;__/ _/ _/ ");
		println("         '._}|==o==\\{_\\/"); 
		println("          /  /-._.--\\  \\_"); 
		println("         // /   /|   \\ \\ \\"); 
		println("        / | |   | \\;  |  \\ \\"); 
		println("       / /  | :/   \\: \\   \\_\\"); 
		println("      /  |  /.'|   /: |    \\ \\"); 
		println("      |  |  |--| . |--|     \\_\\"); 
		println("      / _/   \\ | : | /___--._) \\"); 
		println("     |_(---'-| >-'-| |       '-' ");
		println("            /_/     \\_\\");
}

PUBLIC void teddy(){
		println("          ,-~-. _.---._ ,-~-.");
		println("         / .- ,'       `. -. \\");
		println("         \\ ` /`        ' \\ ' /");
		println("          `-/   'a___a`   \\-'");
		println("            |   ,'(_)`.   |");
		println("            \\  ( ._|_. )  /");
		println("             \\  `.___,'  /");
		println("            .-`._     _,'-.");
		println("          ,'  ,' `---' `.  `.");
		println("         /   /     :     \\   \\");
		println("       ,'   /      :      \\   `.");
		println("     ,'     |      :      |     `.");
		println("    |     ,'|      :      |`.     |");
		println("    `.__,' .-\\     :     /-. `.__,'");
		println("          /   `.   :   ,'   \\");
		println("   .\"\"-.,'      `._:_,'      `.,-\"\".");
		println("  / ,-. `         ) (         ' ,-. \\");
		println(" ( (   `.       ,'   `.       ,'   ) )");
		println("  \\ \\    \\   _,'       `._   /    / /");
		println("   `.`._,'  /             \\  `._,','");
		println("     `.__.-'               `-.__,'");
}

PUBLIC void scrat(){
		println("                               , ");
		println("         ,::.::::.            / `."); 
		println("       ;::        `.         (  ,--."); 
		println("       ,;           :   _,--'\"\\/\"\"-.\\_"); 
		println("      ,:             `./ ,---./( O )) `;"); 
		println("      ;  `.           _,'    (  `-' ) /_."); 
		println("      ;   :         ,'        \\    , (o\\\\"); 
		println("       ;  :         \\  \\-.  -.__--'   \\' )"); 
		println("       ;  ;         /\\ (    `-._`-._   \\/"); 
		println("        ';,        ; : |      -.`._'\\   `."); 
		println("          ;       ;  : `-.,-..  )  \\'\\   ^."); 
		println("           ;     ;   `.__   )))\\ ) (`.\\    \\"); 
		println("            ;   ;        `-`///(, \\ \\ \\)  ,ooo. ");
		println("             ;,;      ;     ``  ))))_;'(  88888p"); 
		println("              ;      ;         ((-='--',-,Y8888'"); 
		println("              ;     :         ;     ,:'-'  `\"'"); 
		println("               ;     `        ;      |"); 
		println("                ;      (_   __   _,-'"); 
		println("                 `---.   ;\"(,-' /                              ____ ");
		println("                      \\ (__/\\_`-.-.                     _____/"); 
		println("                    ,(( '/\\/\\/\\`-;;))             ______//"); 
		println("                   ((\\''/\\/\\/\\/\\/\\/`/\\      _____/  ____/"); 
		println("                   /'/\\/\\/\\/\\/\\/\\/\\/\\/)  __/  _____/"); 
		println("                  (\\/\\/\\/\\/\\/\\/\\/\\/\\_/ _/ ___/ ");
		//println("                   `-|\"\"--\"-.___,--'|-'__/"); 
		//	println("");
}

PUBLIC void print_help(){
		cls();
		println("                                    /   \\ ");      
		println("   _                        )      ((   ))     (");
		println("  (@)                      /|\\      ))_((     /|\\");
		println("  |-|                     / | \\    (/\\|/\\)   / | \\                      (@)");
		println("  | | -------------------/--|-voV---\\`|'/--Vov-|--\\---------------------|-|");
		println("  |-|                         '^`   (o o)  '^`                          | |");
		println("  | |                               `\\Y/'                               |-|");
		println("  |-|                     Simple shell, version 0.0.1                   | |");
		println("  |-|              These shell commands are defined internally.         | |");
		println("  | |                     Type 'help' to see this list.                 |-|");
		println("  | |                   ---------------------------------               |-|");
		println("  | | echo [arg...]   Echo a string on the screen.                      |-|");
		println("  | | cls             Clear the screen.                                 |-|");
		println("  | | version         To see the version info of this operating system. |-|");
		println("  | | about           To show the introduction of this OS.              |-|");
		println("  | | show [name]     To show some interesting pictures.                 |-|");
		println("  | |                                                                   |-|");
		println("  |_|___________________________________________________________________| |");
		println("  (@)              l   /\\ /         ( (       \\ /\\   l                `\\|-|");
		println("                   l /   V           \\ \\       V   \\ l                  (@)");
		println("                   l/                _) )_          \\I");
		println("                                     `\\ /'");
		println("                                       `  ");
		/*
		   println("Simple shell, version 0.0.1");
		   println("These shell commands are defined internally. Type 'help' to see this list.");
		   println("This shell is case sensitive.");
		   newline();
		   println("echo [arg...]   Echo a string on the screen.");
		   println("cls             Clear the screen.");
		   println("version         To see the version info of this operating system.");
		   println("about           To show the introduction of this OS with funny animation.");*/
}

PUBLIC void version(){
		print("Version: ");println(OS_VERSION);
		print("Distributor: ");println(OS_NAME);
		print("Build Date: ");print(__DATE__);
		print(" at ");println(__TIME__);
		println("Build Platform:");
		println("               .-. ");
		println("         .-'``(|||) ");
		println("      ,`\\ \\    `-`.               88                         88 ");
		println("     /   \\ '``-.   `              88                         88"); 
		println("   .-.  ,       `___:    88   88  88,888,  88   88  ,88888, 88888  88   88 ");
		println("  (:::) :        ___     88   88  88   88  88   88  88   88  88    88   88"); 
		println("   `-`  `       ,   :    88   88  88   88  88   88  88   88  88    88   88"); 
		println("     \\   / ,..-`   ,     88   88  88   88  88   88  88   88  88    88   88"); 
		println("      `./ /    .-.`      '88888'  '88888'  '88888'  88   88  '8888 '88888'"); 
		println("         `-..-(   )"); 
		println("               `-`"); 
}

PUBLIC void show(int8* str){
		if(str_equal("scrat",str)){
				cls();
				scrat();
		}else if(str_equal("teddy",str)){
				cls();
				teddy();
		}else if(str_equal("superman",str)){
				cls();
				superman();
		}else{
				print("Sorry, I don't know how to draw ");
				println(str);
				println("\nYou can show these things:\nscrat   An funny animal from Ice Age.\nteddy   A lovely bear.\nsuperman  The guy you have known well.");
		}
}


PUBLIC void process_command(){
		int t,i;
		int8 out[2];

		if(str_start_with("echo",user_input_buff)){
				echo(&(user_input_buff[str_len("echo")]));
		}else if(str_equal("cls",user_input_buff)){
				cls();
		}else if(str_equal("version",user_input_buff)){
				version();
		}else if(str_start_with("about",user_input_buff)){
				print_story_flag=TRUE;
		}else if(str_equal("c",user_input_buff)){
				print_story_flag=FALSE;
				thread_test_flag=FALSE;
		}else if(str_equal("help",user_input_buff)){
				print_help();
		}else if(str_equal("test",user_input_buff)){
				thread_test_flag=TRUE;
		}else if(str_start_with("show",user_input_buff)){
				show(&(user_input_buff[str_len("show")]));
		}else if(str_start_with("cal",user_input_buff)){
				//calculate(&(user_input_buff[str_len("cal")]));
		}else{
				unknown_cmd(user_input_buff);
		}
}

/*PUBLIC boolean login(){

  }*/

PUBLIC void user_input(int8 input){
		int8 out[2];
		out[0]=input;
		out[1]=0;
		if(input==0x3){
				out[0]='\n';
				disp_str(out);
				user_input_buff[user_input_buff_index++]=0;
				process_command();
				user_input_buff_index=0;
				out[0]='#';
				disp_str(out);
		}else if(user_input_buff_index<user_input_buff_max_size){
				if(!(input&FLAG_EXT) 
								&& (input!=0x8) 
								&& (input!=0x9) 
								&& (input!=0xA) 
								&& (input!=0xE) 
								&& (input!=0x2) 
								&& (input!=0x1) 
								&& (input!=0x4) 
								&& (input!=0xC)){
						user_input_buff[user_input_buff_index++]=input;
						//disp_int(user_input_buff[user_input_buff_index-1]);
						out[0]=input & 0xFF;
						//disp_int(out[0]);//debug
						disp_str(out);
				}
		}else{
				print("user_input:");
				disp_int(user_input_buff_index);
				newline();
				print("max_size:");
				disp_int(user_input_buff_max_size);
				newline();
				//	disp_str("Exception!");
		}
}
